package cn.sui.sharejob.config;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import cn.sui.sharejob.core.entity.SysPermission;
import cn.sui.sharejob.core.entity.SysRole;
import cn.sui.sharejob.core.entity.SysUser;
import cn.sui.sharejob.core.service.SysUserService;

public class MyShiroRealm extends AuthorizingRealm {

	@Autowired
	private SysUserService sysUserService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		SysUser sysuser = (SysUser) principals.getPrimaryPrincipal();
		SysRole role = sysuser.getRole();

		authorizationInfo.addRole(role.getName());
		for (SysPermission p : role.getPermissiones()) {
			authorizationInfo.addStringPermission(p.getPermission());
			for (SysPermission subPermission : p.getSubSysPermissiones()) {
				authorizationInfo.addStringPermission(subPermission.getPermission());
			}
		}

		return authorizationInfo;

	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

		UsernamePasswordToken upToken = (UsernamePasswordToken) token;

		SysUser user = sysUserService.getByUserName(upToken.getUsername());

		if (null == user) {
			return null;
		}

		// 5. 根据用户信息的情况, 决定是否需要抛出其他的 AuthenticationException 异常.
		// if (user.getLoginStatus()) {
		// throw new LockedAccountException("用户被锁定");
		// }

		// 6. 根据用户的情况, 来构建 AuthenticationInfo 对象并返回. 通常使用的实现类为: SimpleAuthenticationInfo
		// 以下信息是从数据库中获取的.
		// 1). principal: 认证的实体信息. 可以是 username, 也可以是数据表对应的用户的实体类对象.
		Object principal = user;
		// 2). credentials: 密码.
		Object credentials = user.getPassword(); // "fc1709d0a95a6be30bc5926fdb7f22f4";
		// 3). realmName: 当前 realm 对象的 name. 调用父类的 getName() 方法即可
		String realmName = getName();
		// 4). 盐值.
		ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUserName().getBytes());

		return new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);

	}

}
